
import { APP_ROUTES } from "../enum/app-routes";
import { Token } from "./token";
import Filters from "../filters";
import { SERVER_CODE } from "../enum/web-and-server-code";
import { UniHelp } from "./uni-help";
import { WxHelp } from "./wx-help";
import { AppDeclare } from "./app-declars";
import { ACCOUNT_STATUS } from "../enum/pd-enum";
import Store from "@/store";
import type { ApiUserTypes } from "@/api/api-types/api-user-types";
import appRunTimer from "../class/app-run-tImer";
const currentApp = AppDeclare.getCurrentApp();

/**
 * 根据不同接口的版本，处理接口业务异常及返回数据
 * @param {number} version 接口版本 
 * @returns {ApiVersionHandlerItem} 
 */
type ApiVersionHandlerItem = {
	isApiError : (response : unknown) => boolean,
	getResponseData : (response : unknown) => unknown,
};

/**
 * 对不同版本的接口的结构做处理
 * @param version 
 * @returns 
 */
const apiVersionHandler = (version = 1) : ApiVersionHandlerItem => {
	const m = {
		1: {
			//验证接口是否异常
			isApiError : (response : PDRequest.BaseRes<void>) => {//php接口，没有errcode就算正常
				return Boolean(response && response.errcode !== void 0);
			},
			//获取接口正常返回的数据
			getResponseData : (response: PDRequest.BaseRes<void>) => {
				return response;
			}
		},
		2: {
			isApiError : (response: PDRequest.BaseRes<void>) => {
				return response.errcode !== 200;
			},
			getResponseData : (response: PDRequest.BaseRes<void>) => {
				return response.data;
			}
		},
		3: {
			isApiError : (response: PDRequest.BaseRes<void>) => {
				return response.errcode !== 0;
			},
			getResponseData : (response: PDRequest.BaseRes<void>) => {
				return response.data;
			}
		},
		4: {
			isApiError : (response: PDRequest.BaseRes<void>) => {
				return response.code !== 0;
			},
			getResponseData : (response: PDRequest.BaseRes<void>) => {
				return response.data;
			}
		},
	};
	return m[version];
};


export namespace PDRequest {
	export interface BaseRes<T> {
		errcode ?: number,
		errmsg: string,
		data: T,
		errdata ?: unknown,

		code : number, //新版本接口状态码
		msg : string, //新版本接口错误信息
	}

	type RequestJejecter = ( p :{
		code : number,
		msg : string,
	}) => void;

	/**
	 * php接口，返回结构说明
	 * 	  接口正常 - 直接返回数据：如 : {name : 1}
	 * 	  接口异常 - {errcode : 错误状态码, errmsg : 错误信息}
	 */
	export function request<T>(p: UniApp.RequestOptions, apiVersion = 1, showErrorModal = true): Promise<T> {
		return new Promise((r,j : RequestJejecter) => {
			uni.request({
				header: {
					'token': Token.getToken() || '',
					'channel': '',
					'appid': currentApp!.appid,
					'utype': currentApp!.userType, //用户类型
					'client': currentApp!.client, //客服端类型
				},
				...p,
				url: import.meta.env.VITE_BASE_API_URI + (p.url || ''),
				timeout : 20 * 1000,
				success: res => {
					//请求异常
					if (res.statusCode !== 200) {
						UniHelp.toast('网络请求异常，请稍后重试');
						WxHelp.WxLogger.error('网络请求异常', p);
						return j({
							code : 0,
							msg : '网络请求异常',
						});
					};
					const serverRes = res.data as BaseRes<T>;
					//是否业务异常
					const isBusinessError = apiVersionHandler(apiVersion).isApiError(serverRes);

					//业务正常
					if (!isBusinessError) {
						return r(apiVersionHandler(apiVersion).getResponseData(serverRes) as T);
					};
					

					try {
						UniHelp.loading(false);
					} catch (e) { };
					//业务异常
					//token异常
					if ([SERVER_CODE.tokenError, SERVER_CODE.tokenEmpty].includes(serverRes?.errcode as SERVER_CODE)) {
						appRunTimer.stop();
						UniHelp.modal('登录状态异常，点击【确定】刷新小程序').then(() => {
							Store.user().loginFinished = false;
							UniHelp.reLaunch(APP_ROUTES.index);
						});
						return j({
							code : SERVER_CODE.tokenError,
							msg : 'token错误'
						});
					};
					//账户异常 前往账户异常承接页
					if (
						serverRes.errdata 
						&& (serverRes.errdata as ApiUserTypes.AccountErrorRes).status 
						&& [ACCOUNT_STATUS.forbidden, ACCOUNT_STATUS.freeze].includes( (serverRes.errdata as ApiUserTypes.AccountErrorRes).status as ACCOUNT_STATUS )
					) {
						Store.user().accountErrorData = serverRes.errdata as ApiUserTypes.AccountErrorRes;
						UniHelp.reLaunch(APP_ROUTES.accountError);
						return j({
							code : 0,
							msg : '账户异常'
						});
					};
					
					//普通业务异常
					WxHelp.WxLogger.info('业务请求异常', {
						req: p,
						res: serverRes,
						openid : Store.user().openid,
						token: Token.getToken(),
						trigger_time: Filters.Common.dateFormat(Date.now(), 'YYYY/MM/DD HH:mm:ss')
					});
					//如果没有关闭错误提示，则给出业务错误提示信息
					(showErrorModal !== false) && UniHelp.modal(serverRes.errmsg || serverRes.msg);
					return j({
						code : serverRes?.errcode || serverRes.code,
						msg : serverRes.errmsg || serverRes.msg,
					});
				},
				fail: err => {
					WxHelp.WxLogger.error('网络请求异常', p);
					try {
						UniHelp.loading(false);
					} catch (e) { };
					UniHelp.toast('网络请求异常，请稍后重试');
					return j({
						code : 0,
						msg : JSON.stringify(err),
					});
				}
			});
		});
	}
}

